﻿using Kingdee.BOS.App;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn;
using Kingdee.BOS.Core.Metadata.ConvertElement.PlugIn.Args;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Util;
using System;
using System.ComponentModel;

namespace LM.YF.K3Cloud.Plugin
{
    /// <summary>
    /// 分步式调出单到货运单单据转换插件
    /// </summary>
    /// <remarks>
    /// 功能：1、如果存在运输路线，则获取运输路线价
    /// 2、重新计算重量占比
    /// 创建人：lxl
    /// 创建日期：2024-6-25
    /// 修改信息（1）：修改人，修改日期，修改内容
    /// </remarks>
    [Description("分步式调出单到货运单单据转换插件"), HotUpdate]
    public class TransfToDelivCvtPlugin : AbstractConvertPlugIn
    {
        /// <summary>
        /// 解析字段映射关系，并构建查询参数。
        /// 这里可以加入你想要的字段
        /// </summary>
        /// <param name="e">事件参数包</param>
        public override void OnQueryBuilderParemeter(QueryBuilderParemeterEventArgs e)
        {
            //e.SelectItems.Add(new SelectorItemInfo("")); 添加你需要添加的字段的Key
        }

        /// <summary>
        /// 创建关联关系后事件
        /// </summary>
        /// <param name="e">事件参数包</param>
        public override void OnAfterCreateLink(CreateLinkEventArgs e)
        {

        }

        /// <summary>
        /// 下推/选单时，根据字段映射,向目标字段填充值
        /// </summary>
        /// <param name="e"></param>
        public override void OnFieldMapping(FieldMappingEventArgs e)
        {
            switch (e.TargetField.Key.ToUpperInvariant())
            {
                //case "FXXX": 选单时的目标字段Key【大写】，可以根据条件设置值e.MapValue
                //    e.MapValue = "";
                //   break;
                case "":
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 下推/选单，自动填充目标字段值完毕后，这里可以对填充值进行修复，处理
        /// </summary>
        /// <param name="e"></param>
        public override void OnAfterFieldMapping(AfterFieldMappingEventArgs e)
        {
            //SetFilter(e);
        }

        /// <summary>
        /// 最后触发：单据转换后事件
        /// </summary>
        /// <param name="e"></param>
        public override void AfterConvert(AfterConvertEventArgs e)
        {
            ExtendedDataEntity[] allBillDataObjs = e.Result.FindByEntityKey("FBillHead");
            //遍历单据转换之后的数据
            foreach (ExtendedDataEntity data in allBillDataObjs)
            {
                ExtendedDataEntity myData = data;

                #region 计算组单后重量占比、交货数量占比
                //获取整单交货数量-基本单位
                decimal F_RDLV_NotcQtyTotal = Convert.ToDecimal(data["F_RDLV_NotcQtyTotal"]);
                //获取整单重量
                decimal F_RDLV_TotalWeigh = Convert.ToDecimal(data["F_RDLV_TotalWeigh"]);
                //交货数量占比
                decimal fQtyRateLeft = 1;
                //重量占比
                decimal fWeightRateLeft = 1;
                DynamicObjectCollection fEntity = data["FEntity"] as DynamicObjectCollection;
                foreach (DynamicObject o2 in fEntity)
                {
                    //获取当前行的索引
                    int fIndex = fEntity.IndexOf(o2);
                    //获取销售数量-基本单位
                    decimal FQty = Convert.ToDecimal(o2["F_RDLV_OutQty"]);
                    if (F_RDLV_NotcQtyTotal > 0)
                    {
                        decimal F_RDLV_QtyRate = 0;
                        //前面都按照重量计算
                        if (fIndex < fEntity.Count - 1)
                        {
                            //计算交货数量占比
                            F_RDLV_QtyRate = Math.Round(FQty / F_RDLV_NotcQtyTotal, 6);
                            //扣减占比
                            fQtyRateLeft = fQtyRateLeft - F_RDLV_QtyRate;
                        }
                        else//最后一行倒挤出占比
                        {
                            F_RDLV_QtyRate = fQtyRateLeft;
                        }
                        o2["F_RDLV_QtyRate"] = F_RDLV_QtyRate;
                    }

                    //获取分录重量
                    decimal F_RDLV_OutWeight = Convert.ToDecimal(o2["F_RDLV_RowWeigh"]);
                    decimal F_RDLV_WeightRate;
                    if (F_RDLV_TotalWeigh > 0)
                    {
                        //前面都按照重量计算
                        if (fIndex < fEntity.Count - 1)
                        {
                            //计算交货重量占比
                            F_RDLV_WeightRate = Math.Round(F_RDLV_OutWeight / F_RDLV_TotalWeigh, 6);
                            //扣减占比
                            fWeightRateLeft = fWeightRateLeft - F_RDLV_WeightRate;
                        }
                        else//最后一行倒挤出占比
                        {
                            F_RDLV_WeightRate = fWeightRateLeft;
                        }
                        o2["F_RDLV_WeightRate"] = F_RDLV_WeightRate;
                    }
                }
                #endregion
                #region 获取运输路线、运输计价表、运输金额
                //运输计划点
                DynamicObject F_RDLV_StartCode = data["F_RDLV_StartCode"] as DynamicObject;

                //获取运输路线
                DynamicObject F_RDLV_TransferRute = data["F_RDLV_TransferRute"] as DynamicObject;
                //获取运费计价方式
                string F_RDLV_PriceTypeId = Convert.ToString(data["F_RDLV_PriceType"]);
                //当选择了运输路线,并且是重量计价时，获取路线价,其他方式计价必须要填写数量才有价格
                if (F_RDLV_TransferRute != null && F_RDLV_PriceTypeId == "1" && F_RDLV_StartCode != null)
                {
                    //运输计划点
                    string F_RDLV_StartCodeid = F_RDLV_StartCode?["id"].ToString();
                    //运输路线
                    string F_RDLV_TransferRuteId = F_RDLV_TransferRute?["id"].ToString();

                    //组单日期
                    string date = data["F_RDLV_Date"]?.ToString();

                    //获取当前路线的价格：时间、路线过滤，按照等级数量升序排列，获取第一条满足的数据
                    //暂时不考虑单位、币种
                    string strSql = $@"select a.fid, b.F_RDLV_ClassType,F_RDLV_ClassQty ,F_RDLV_Price,F_RDLV_Unit,F_RDLV_Currency from RDLV_t_ShipRutePrice a 
                        inner join RDLV_t_ShipRutePriceEntry b on a.fid=b.fid and a.FDOCUMENTSTATUS='C'and a.F_RDLV_ShipRute={F_RDLV_TransferRuteId} 
                        and '{date}' between F_RDLV_StartDate and F_RDLV_EndDate and F_RDLV_ShipCode={F_RDLV_StartCodeid} 
                        and {F_RDLV_TotalWeigh}>0 
                        and ( ({F_RDLV_TotalWeigh}<=F_RDLV_ClassQty and F_RDLV_ClassType='小于等于' ) 
                        or({F_RDLV_TotalWeigh}<F_RDLV_ClassQty and F_RDLV_ClassType='小于' ))
                        order by F_RDLV_ClassQty ";
                    DynamicObjectCollection getData = DBUtils.ExecuteDynamicObject(Context, strSql);
                    if (getData != null && getData.Count > 0)
                    {
                        //获取第一行满足条件的数据，即为运费单价
                        decimal fPrice = Convert.ToDecimal(getData[0]["F_RDLV_Price"]);
                        //赋值运费的单价
                        myData["F_RDLV_PRICE"] = fPrice;
                        //计算整单运价
                        decimal F_RDLV_ShipAmt = fPrice * F_RDLV_TotalWeigh;
                        decimal fShipAmtLeft = F_RDLV_ShipAmt;
                        //赋值总运费
                        myData["F_RDLV_ShipAmt"] = F_RDLV_ShipAmt;
                        //赋值运费计价单位
                        BaseDataField funitFileld = e.TargetBusinessInfo.GetField("F_RDLV_ShipUnit") as BaseDataField;
                        string F_RDLV_ShipUnit = Convert.ToString(getData[0]["F_RDLV_Unit"]);
                        IViewService viewService0 = ServiceHelper.GetService<IViewService>();
                        DynamicObject[] froutObjs0 = viewService0.LoadFromCache(this.Context,
                            new object[] { F_RDLV_ShipUnit },
                            funitFileld.RefFormDynamicObjectType);
                        myData["F_RDLV_ShipUnit_id"] = F_RDLV_ShipUnit;
                        myData["F_RDLV_ShipUnit"] = froutObjs0[0];

                        //赋值使用的价格表
                        BaseDataField froutFileld = e.TargetBusinessInfo.GetField("F_RDLV_ShipPriceId") as BaseDataField;
                        string F_RDLV_ShipPriceId = Convert.ToString(getData[0]["fid"]);
                        IViewService viewService = ServiceHelper.GetService<IViewService>();
                        DynamicObject[] froutObjs = viewService.LoadFromCache(this.Context,
                            new object[] { F_RDLV_ShipPriceId },
                            froutFileld.RefFormDynamicObjectType);
                        myData["F_RDLV_ShipPriceId_id"] = F_RDLV_ShipPriceId;
                        myData["F_RDLV_ShipPriceId"] = froutObjs[0];

                        //分配到各个分录行
                        DynamicObjectCollection FEntity = data["FEntity"] as DynamicObjectCollection;
                        for (int i = 0; i < FEntity.Count; i++)
                        {
                            //前面行按照占比计算，最后一行到挤出数据
                            if (i < FEntity.Count - 1 && F_RDLV_TotalWeigh > 0)
                            {
                                //计算重量占比并赋值
                                decimal F_RDLV_WeightRate = Convert.ToDecimal(FEntity[i]["F_RDLV_WeightRate"]);
                                //计算每行分摊的运费
                                decimal F_RDLV_RowAmt = F_RDLV_ShipAmt * F_RDLV_WeightRate;
                                FEntity[i]["F_RDLV_RowAmt"] = F_RDLV_RowAmt;
                                //扣减整单剩余金额
                                fShipAmtLeft = fShipAmtLeft - F_RDLV_RowAmt;
                            }
                            else
                            {   //最后一行到挤出数据
                                FEntity[i]["F_RDLV_RowAmt"] = fShipAmtLeft;
                            }
                        }
                    }
                    else//没有计价信息，清空
                    {
                        //赋值总运费
                        myData["F_RDLV_ShipAmt"] = 0;
                        //清空运费单价
                        myData["F_RDLV_PRICE"] = 0;
                        //赋值使用的价格表
                        //myData["F_RDLV_ShipPriceId"] = 0;
                        myData["F_RDLV_ShipPriceId"] = null;
                    }
                }
                #endregion
            }
        }
    }
}